import { isNull } from "@/utils/validate";

interface FormatObj {
  y: number;
  m: number;
  d: number;
  h: number;
  i: number;
  s: number;
  a: number;
}

interface TreeNode {
  id: string;
  name: string;
  parentId: string | null;
  children?: TreeNode[];
}

interface Point {
  clientX: number;
  clientY: number;
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 格式化时间
 * @param time
 * @param cFormat
 * @returns {string|null}
 */
export function parseTime(time: Date | string | number, cFormat?: string): string | null {
  if (arguments.length === 0) {
    return null;
  }
  const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
  let date: Date;
  if (typeof time === "object") {
    date = time;
  } else {
    if (typeof time === "string" && /^[0-9]+$/.test(time)) {
      time = parseInt(time);
    }
    if (typeof time === "number" && time.toString().length === 10) {
      time = time * 1000;
    }
    date = new Date(time);
  }
  const formatObj: FormatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result: string, key: keyof FormatObj) => {
    let value = formatObj[key];
    if (key === "a") {
      return ["日", "一", "二", "三", "四", "五", "六"][value];
    }
    if (result.length > 0 && value < 10) {
      value = Number("0" + value);
    }
    return String(value || 0);
  });
  return time_str;
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 格式化时间
 * @param time
 * @param option
 * @returns {string}
 */
export function formatTime(time: number | string, option?: string): string {
  if (("" + time).length === 10) {
    time = parseInt(time as string) * 1000;
  } else {
    time = +time;
  }
  const d = new Date(time);
  const now = Date.now();

  const diff = (now - d.getTime()) / 1000;

  if (diff < 30) {
    return "刚刚";
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + "分钟前";
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + "小时前";
  } else if (diff < 3600 * 24 * 2) {
    return "1天前";
  }
  if (option) {
    return parseTime(time, option) || "";
  } else {
    return (
      d.getMonth() +
      1 +
      "月" +
      d.getDate() +
      "日" +
      d.getHours() +
      "时" +
      d.getMinutes() +
      "分"
    );
  }
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 将url请求参数转为json格式
 * @param url
 * @returns {{}|any}
 */
export function paramObj(url: string): Record<string, string> {
  const search = url.split("?")[1];
  if (!search) {
    return {};
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, " ") +
      '"}'
  );
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 父子关系的数组转换成树形结构数据
 * @param data
 * @returns {*}
 */
export function translateDataToTree(data: TreeNode[]): TreeNode[] {
  const parent = data.filter(
    (value) => value.parentId === "undefined" || value.parentId == null
  );
  const children = data.filter(
    (value) => value.parentId !== "undefined" && value.parentId != null
  );
  const translator = (parent: TreeNode[], children: TreeNode[]) => {
    parent.forEach((parent) => {
      children.forEach((current, index) => {
        if (current.parentId === parent.id) {
          const temp = JSON.parse(JSON.stringify(children));
          temp.splice(index, 1);
          translator([current], temp);
          if (parent.children) {
            parent.children.push(current);
          } else {
            parent.children = [current];
          }
        }
      });
    });
  };
  translator(parent, children);
  return parent;
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 树形结构数据转换成父子关系的数组
 * @param data
 * @returns {[]}
 */
export function translateTreeToData(data: TreeNode[]): TreeNode[] {
  const result: TreeNode[] = [];
  data.forEach((item) => {
    const loop = (data: TreeNode) => {
      result.push({
        id: data.id,
        name: data.name,
        parentId: data.parentId,
      });
      const child = data.children;
      if (child) {
        for (let i = 0; i < child.length; i++) {
          loop(child[i]);
        }
      }
    };
    loop(item);
  });
  return result;
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 10位时间戳转换
 * @param time
 * @returns {string}
 */
export function tenBitTimestamp(time: number): string {
  const date = new Date(time * 1000);
  const y = date.getFullYear();
  let m: string | number = date.getMonth() + 1;
  m = m < 10 ? "0" + m : m;
  let d: string | number = date.getDate();
  d = d < 10 ? "0" + d : d;
  let h: string | number = date.getHours();
  h = h < 10 ? "0" + h : h;
  let minute: string | number = date.getMinutes();
  let second: string | number = date.getSeconds();
  minute = minute < 10 ? "0" + minute : minute;
  second = second < 10 ? "0" + second : second;
  return y + "年" + m + "月" + d + "日 " + h + ":" + minute + ":" + second; //组合
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 13位时间戳转换
 * @param time
 * @returns {string}
 */
export function thirteenBitTimestamp(time: number): string {
  const date = new Date(time / 1);
  const y = date.getFullYear();
  let m: string | number = date.getMonth() + 1;
  m = m < 10 ? "0" + m : m;
  let d: string | number = date.getDate();
  d = d < 10 ? "0" + d : d;
  let h: string | number = date.getHours();
  h = h < 10 ? "0" + h : h;
  let minute: string | number = date.getMinutes();
  let second: string | number = date.getSeconds();
  minute = minute < 10 ? "0" + minute : minute;
  second = second < 10 ? "0" + second : second;
  return y + "年" + m + "月" + d + "日 " + h + ":" + minute + ":" + second; //组合
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description 获取随机id
 * @param length
 * @returns {string}
 */
export function uuid(length = 32) {
  const num = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
  let str = "";
  for (let i = 0; i < length; i++) {
    str += num.charAt(Math.floor(Math.random() * num.length));
  }
  return str;
}

/**
 * 给URL追加参数
 * url
 * parameter 参数名
 * value  参数值
 */
export function urlAddArgs(urls: string, parameter: string, value: string): string {
  let buf = "";
  if (!isNull(urls)) {
    buf = urls;
    if (urls.indexOf("?") > -1) {
      //已经有参数
      buf += "&";
    } else {
      buf += "?";
    }
    buf += parameter;
    buf += "=";
    buf += value;
  }
  return buf.toString();
}

/**
 * 给URL追加参数
 * url
 * parameter 参数名
 * value  参数值
 */
export function urlAddArgsByData(urls: string, data: string): string {
  let buf = "";
  if (!isNull(urls)) {
    buf = urls;
    if (urls.indexOf("?") > -1) {
      //已经有参数
      buf += "&";
    } else {
      buf += "?";
    }
    buf += data;
  }
  return buf.toString();
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description m到n的随机数
 * @param m
 * @param n
 * @returns {number}
 */
export function random(m: number, n: number): number {
  return Math.floor(Math.random() * (m - n) + n);
}

// 按钮倒计时锁定
export function vueButtonClickBan(point: Point, second: number, isAddClass?: boolean): void {
  let el = document.elementFromPoint(point.clientX, point.clientY);
  if (el !== null && el !== undefined) {
    for (let i = 0; i < 5; i++) {
      if (el && "BUTTON" === el.nodeName) {
        break;
      }
      if (el) {
        el = el.parentElement;
      }
    }
    if (el && "BUTTON" !== el.nodeName) {
      el = null;
    }
    if (el && el instanceof HTMLElement) {
      buttonClickBan(el, second, isAddClass);
    }
  }
}

// 按钮倒计时锁定
export function buttonClickBan(el: HTMLElement, second: number, isAddClass?: boolean): void {
  if (el === null || el === undefined) {
    return;
  }
  if (isAddClass === undefined || isAddClass) {
    el.classList.add("is-disabled");
  }
  el.style.pointerEvents = "none";

  const textSpan = el.querySelector("span");
  if (textSpan) {
    const btnText = textSpan.textContent || "";
    textSpan.textContent = btnText + " (" + second + ")";

  for (let i = second; i > 0; i--) {
    setTimeout(
      (function (i) {
        return function () {
            if (textSpan) {
              textSpan.textContent = btnText + " (" + (second - i) + ")";
          if (i === second) {
            if (isAddClass === undefined || isAddClass) {
              el.classList.remove("is-disabled");
            }
                el.style.pointerEvents = "auto";
                textSpan.textContent = btnText;
              }
          }
        };
      })(i),
      i * 1000
    );
    }
  }
}

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description addEventListener
 * @type {function(...[*]=)}
 */
export const on = (function () {
  return function (
    element: HTMLElement,
    event: string,
    handler: EventListenerOrEventListenerObject,
    useCapture = false
  ): void {
    if (element && event && handler) {
      element.addEventListener(event, handler, useCapture);
    }
  };
})();

/**
 * @copyright chuzhixin 1204505056@qq.com
 * @description removeEventListener
 * @type {function(...[*]=)}
 */
export const off = (function () {
  return function (
    element: HTMLElement,
    event: string,
    handler: EventListenerOrEventListenerObject,
    useCapture = false
  ): void {
    if (element && event) {
      element.removeEventListener(event, handler, useCapture);
    }
  };
})();
